package com.mol.market.widget;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Looper;
import android.util.SparseIntArray;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.mol.market.Constants;
import com.mol.market.R;
import com.mol.market.common.util.CacheManager;
import com.mol.market.common.util.ImageUtils;
import com.mol.market.common.util.Utils;
import com.mol.market.ui.SearchActivity;
import com.mol.market.ui.SplashActivity;
import com.mol.market.ui_v4.ProductDetailActivity;

public class SlotMachinesWidget extends AppWidgetProvider{
    
    private static final String TAG = "widget";
    /*It should not be modified by hand.*/
    private static final int ARGS_BOX_WIDTH   = 96;
    private static final int ARGS_BOX_HEIGHT  = 96;
    private static final int ARGS_ICON_WIDTH  = 72;
    private static final int ARGS_ICON_HEIGHT = 72;
    private static final String ACTION_NET_ERROR ="com.mol.market.action.rool";
    private static final String ACTION_TIEROD="com.mol.market.action.tierod";
    public static final String ACTION_DESTROY_START = "com.mol.market.action.destroyAndStart";
    public static final String ACTION_APP = "com.mol.market.action.appicon";
    public static final String INTENT_APP_INFO = "com.mol.market.appinfo";
    /*发广播启动Activity的Extra的Name**/
    public static final String INTENT_EXTRA = "extra.activity";
    /*启动首页**/
    public static final int EXTRA_HOMETABACTIVITY = 1;
    /*启动搜索页**/
    public static final int EXTRA_SEARCHACTIVITY = 2;
    /*启动产品详情页**/
    public static final int EXTRA_PRODUCTDETAILACTIVITY = 3;
    /**当图片数量大于WINNING_MIN_SIZE时，才有机会中奖*/
    private static final int WINNING_MIN_SIZE = 40;
    /*the index of the PendingIntent**/
    public static final AtomicInteger indexOfPendingIntent = new AtomicInteger(0);
    /**滚动时间*/
    private static final long TIME_ROLL    =  3 * 1000;
    /**拉杆还原时间*/
    private static final long TIME_TIEROD  =  500;
    /**滚动速度是否可变*/
    private static final boolean ROLL_SPEED_CHANGE = false;
    /**三个Box是否随即顺序启动*/
    private static final boolean ROLL_ORDER_RANDOM = false;
    /**变速器*/
    private static final Interpolator interpolator = new AccelerateDecelerateInterpolator();
    /**AppInfoList */
    private static final ArrayList<AppInfo> mAppInfo = new ArrayList<AppInfo>();
    /**the flag of animation*/
    private static final AtomicBoolean isRealEnd = new AtomicBoolean(true);
    /**the flag will tell program, should be stop the animation*/
    private static final AtomicBoolean isShouldBeEnd = new AtomicBoolean(false);
    //random seed
    public final Random ran = new Random();
    /**{@link #ROLL_SPEED_CHANGE} 为false,则{@link #SPEED_ROLL_MIN}无意义*/
    private static final long SPEED_ROLL = 50;
    private static final long SPEED_ROLL_MIN = 10; 
    /**the roll start time || {@link #ROLL_SPEED_CHANGE} 为false，则无意义*/
    private static long m_roll_start_time = 0;


    private AppWidgetManager mManager = null;
    
    //中奖相关信息
    public static final SparseIntArray crazyResult = new SparseIntArray();
    public static final byte APP_A = 1;
    public static final byte APP_B = 2;
    public static final byte APP_C = 3;
    public static final AtomicBoolean havaChanceWinning = new AtomicBoolean(true);
    
    //初始化图片资源
    public static int[] crazyResource,appiconResource;
    static {
        crazyResource = new int[]{
                //a suit of the app animation
                R.drawable.logo01, 
                R.drawable.logo02, 
                R.drawable.logo03,
                R.drawable.logo04, 
                R.drawable.logo05,
        };
        
        //默认图片
        appiconResource = new int[]{
                //the app icon
                R.drawable.app_icon,
//                R.drawable.icon_360,
//                R.drawable.icon_qq
        };
    }
    
    /**
     * 更新
     */
    public void onUpdate(final Context context, final AppWidgetManager appWidgetManager,
            final int[] appWidgetIds) {
//        Log.i(TAG, "onUpdate" + String.format("共有%d个widget", appWidgetIds.length));
        
        //add the bitmap and setOnClickListener
        RemoteViews remoteViews = getRemoteView(context);
        remoteViews.setImageViewBitmap(R.id.iv_app_01,
                scaleBitmap(createRandomIcon(context, APP_A, mAppInfo)));
        remoteViews.setImageViewBitmap(R.id.iv_app_02,
                scaleBitmap(createRandomIcon(context, APP_B, mAppInfo)));
        remoteViews.setImageViewBitmap(R.id.iv_app_03,
                scaleBitmap(createRandomIcon(context, APP_C, mAppInfo)));
        remoteViews.setOnClickPendingIntent(R.id.iv_logo,
                PendingFactory.createActionByFlag(context, EXTRA_HOMETABACTIVITY));
        remoteViews.setOnClickPendingIntent(R.id.iv_serach,
                PendingFactory.createActionByFlag(context, EXTRA_SEARCHACTIVITY));
        remoteViews.setOnClickPendingIntent(R.id.iv_tierod,
                PendingFactory.createCommonAction(context, ACTION_TIEROD));
        
        //update the appWidgetManager
        appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
    }
    

    
    /**
     * 第一个Widget组件启动时触发
     */
    public void onEnabled(Context context) {
//        Log.i(TAG, "onEnabled");
    }

    /**
     * 最后一个Widget组件关闭时触发
     */
    public void onDisabled(Context context) {
//        Log.i(TAG, "onDisabled");
        release(context);
    }

    /**
     * 任一Widget组件被删除时触发
     */
    public void onDeleted(Context context, int[] appWidgetIds) {
//        Log.i(TAG, "onDeleted");
    }

    /**
     * 以上函数触发前会先触发该函数，一般不需要重写
     */
    
    public void onReceive(final Context context, Intent intent) {
//        Log.i(TAG, "onReceive" + intent.getAction());
        super.onReceive(context, intent);
        
        if(intent.getAction().equals(ACTION_NET_ERROR)){
            showTip(context, context.getString(R.string.no_valid_network));
            return;
        }
        
        if(intent.getAction().equals(ACTION_APP)){
            @SuppressWarnings("unchecked")
            final ArrayList<HashMap<String, Object>> list = (ArrayList<HashMap<String, Object>>) intent
                    .getSerializableExtra(INTENT_APP_INFO);
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    
                    release(context);
                    
                    CacheManager manager = CacheManager.getInstance(context);
                    //来自网络的需要自己释放
                    boolean isFromInternet;
                    
                    for(int i=0; i<list.size(); i++){
                        HashMap<String, Object> item = list.get(i);
                        
                        Bitmap icon = manager.getDrawableFromCache(context,
                                (String) item.get(Constants.KEY_PRODUCT_ICON_URL));
                        
                        if (icon == null) {
                            isFromInternet = true;
                            icon = ImageUtils.getImageFromUrl(context,
                                    (String) item.get(Constants.KEY_PRODUCT_ICON_URL), false);
                        }else{
                            isFromInternet = false;
                        }
                        if(icon == null){
                            //如果得不到图片，就不记录这个信息
                            continue;
                        }
                        mAppInfo.add(new AppInfo().setBitmap(icon)
                                .setName((String) item.get(Constants.KEY_PRODUCT_NAME))
                                .setPid((String) item.get(Constants.KEY_PRODUCT_ID))
                                .setIsFromInternet(isFromInternet));
                    }
                }
            }, 0);
            return;
        }
        
        if(intent.getAction().equals(ACTION_TIEROD)){

            Utils.trackEvent(context, Constants.WIDGET, Constants.WIDGET_PLAY);
            if(!isRealEnd.get()){
                //if this flag is false,the animation is not end.
                return;
            }
            isRealEnd.set(false);
            // now,let's reset the res for widget
            resetText(context);
            resetImageViewOnClick(context);
            resetIndexOfPendingIntent();
           
            RemoteViews remoteViews = getRemoteView(context);
            remoteViews.setImageViewResource(R.id.iv_tierod, R.drawable.tierod_start);
            
            //update the widget
            update(context,remoteViews);
            //record the start time
            m_roll_start_time = System.currentTimeMillis();
            
            //滚动停止
            new Timer().schedule(new TimerTask() {
                
                @Override
                public void run() {
                    //tell the program,should be stop
                    isShouldBeEnd.set(true);
                }
            }, TIME_ROLL);

            //还原拉杆
            new Timer().schedule(new TimerTask() {
                
                @Override
                public void run() {
                    RemoteViews remoteViews = getRemoteView(context);
                    remoteViews.setImageViewResource(R.id.iv_tierod, R.drawable.tierod_ready);
                    update(context,remoteViews);
                }
            }, TIME_TIEROD);
 
            roll(context);
            return;
        }
        
        //销毁之前的页面，打开新的Activity
        if(intent.getAction().equals(ACTION_DESTROY_START)){
            
            if(!isRealEnd.get()){
                //在roll时，所有触发按钮都取消效果。
                return ;
            }
            
            final int flag = intent.getIntExtra(INTENT_EXTRA, -1);
            switch (flag) {
            case EXTRA_HOMETABACTIVITY:
                context.startActivity(new Intent(context, SplashActivity.class)
                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                        .addCategory(Intent.CATEGORY_LAUNCHER)
                        .setAction(Intent.ACTION_MAIN));
                break;
            case EXTRA_SEARCHACTIVITY:
                context.startActivity(new Intent(context, SearchActivity.class)
                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
                break;
            case EXTRA_PRODUCTDETAILACTIVITY:
                intent.setClass(context,ProductDetailActivity.class);
                context.startActivity(intent);
                break;
            default:
                throw new IllegalArgumentException("flag illegal, flag -> " + flag);
            }
            return ;
        }
    }
    
    private void roll(final Context context){
        
        final Handler roll = new Handler(Looper.getMainLooper());
        roll.post(new Runnable() {
           
            long speed = SPEED_ROLL;
            int index = 0;
            
            int round_app_01 = ran.nextInt(3);
            int round_app_02 = ran.nextInt(3);
            int round_app_03 = ran.nextInt(3);
            

            FrameControls frameControls = new FrameControls();
            
            @Override
            public void run() {
                frameControls.setStart(System.currentTimeMillis());
                
                if(!ROLL_ORDER_RANDOM){
                    round_app_01 = 1;
                    round_app_02 = 2;
                    round_app_03 = 0;
                }
                
                speed = createSpeed(speed);
                frameControls.setFrame(speed);
                
                RemoteViews remote = getRemoteView(context);
                remote.setImageViewBitmap(
                        R.id.iv_app_01,
                        drawableToBitmap(context, crazyResource[(index + round_app_01)
                                % crazyResource.length]));
                remote.setImageViewBitmap(
                        R.id.iv_app_02,
                        drawableToBitmap(context, crazyResource[(index + round_app_02)
                                % crazyResource.length]));
                remote.setImageViewBitmap(
                        R.id.iv_app_03,
                        drawableToBitmap(context, crazyResource[(index + round_app_03)
                                % crazyResource.length]));
                update(context,remote);
                
                if(index < crazyResource.length){
                    index++;
                }else{
                    //reset the index;
                    index= 0;
                    if(isShouldBeEnd.get()){
                        remote.setImageViewBitmap(R.id.iv_app_01,
                                scaleBitmap(createRandomIcon(context, APP_A, mAppInfo)));
                        remote.setImageViewBitmap(R.id.iv_app_02,
                                scaleBitmap(createRandomIcon(context, APP_B, mAppInfo)));
                        remote.setImageViewBitmap(R.id.iv_app_03,
                                scaleBitmap(createRandomIcon(context, APP_C, mAppInfo)));
                        update(context,remote);
                        
                        if(isCrazyWinning()){
                            showTip(context, context.getString(R.string.no_valid_network));
                        }else{
                            //do nothing
                        }
                        
                        //reset the flag
                        isShouldBeEnd.set(false);
                        isRealEnd.set(true);
                        
                        return ;
                    }
                       
                }
                frameControls.setEnd(System.currentTimeMillis());
                roll.postDelayed(this, frameControls.getReal());
            }
        });
    }
    
    /**
     * handle the bitmap
     * @param context
     * @param id
     * @return
     */
    private Bitmap drawableToBitmap(Context context,int id){
        return BitmapFactory.decodeResource(context.getResources(), id);
    }
    
    /**
     * 为ImageView量身定制Bitmap
     * @param context
     * @param content
     * @return
     */

    private Bitmap scaleBitmap(Bitmap content){
        
        if(content == null){
            return null;
        }
        
        Bitmap result = Bitmap.createBitmap(
                ARGS_BOX_WIDTH, 
                ARGS_BOX_HEIGHT, 
                Config.ARGB_8888);
        
        Bitmap real_content = Bitmap.createScaledBitmap(
                content, 
                ARGS_ICON_WIDTH, 
                ARGS_ICON_HEIGHT, 
                true);
        
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        Canvas canvas = new Canvas();
        canvas.setBitmap(result);
        
        //draw the content(bitmap)
        canvas.drawBitmap(
                real_content, 
                (ARGS_BOX_WIDTH - ARGS_ICON_WIDTH) / 2, 
                (ARGS_BOX_HEIGHT - ARGS_ICON_HEIGHT) / 2,
                paint);
        
        //recycle
//        real_content.recycle();
//        real_content = null;
        
        return result;
    }
    /**
     * @param nowSpeed
     * @param speedChange
     * @return
     */
    private long createSpeed(long nowSpeed){
        if(ROLL_SPEED_CHANGE){
            long past_time = System.currentTimeMillis() - m_roll_start_time;
            //计算时间的单位因子 rollTime / 10;
            long time_factor = TIME_ROLL / 10;
            int factor = (int) (past_time/time_factor);
            //得到进度
            float interpolator_factor = factor * 0.1f;
            float progress = interpolator.getInterpolation(interpolator_factor);
            float interpolator_speed = progress
                    / (interpolator_factor == 0 ? 0.1f : interpolator_factor);
            //得到当前速度
            long speed = (long) (interpolator_speed * SPEED_ROLL);
            
            return speed == 0 ? SPEED_ROLL_MIN : speed;
        }
        return nowSpeed;
    }
    
    /**
     * 得到随即的icon
     * @return
     */
    private Bitmap createRandomIcon(Context context,byte appTag){
        int result = appiconResource[ran.nextInt(appiconResource.length)];
        crazyResult.put(appTag, result);
        
        RemoteViews views = getRemoteView(context);
        //默认图标，点击提示网络不通
        if (appTag == APP_A) {
            views.setOnClickPendingIntent(R.id.iv_app_01,
                    PendingFactory.createCommonAction(context, ACTION_NET_ERROR));
        } else if (appTag == APP_B) {
            views.setOnClickPendingIntent(R.id.iv_app_02,
                    PendingFactory.createCommonAction(context, ACTION_NET_ERROR));
        } else {
            views.setOnClickPendingIntent(R.id.iv_app_03,
                    PendingFactory.createCommonAction(context, ACTION_NET_ERROR));
        }
        update(context, views);
        return drawableToBitmap(context, result);
    }
    
    /**
     * 得到random的icon，如果是gfan获取的，并在下方显示应用的名字.
     * @param context
     * @param appTag
     * @param list
     * @return
     */

    private Bitmap createRandomIcon(Context context,byte appTag, ArrayList<AppInfo> list){
        if(list.size() < 3){
           havaChanceWinning.set(false);
           return createRandomIcon(context,appTag);
        }
        
        //if size > XX , have chance;
        if(list.size() > WINNING_MIN_SIZE){
            havaChanceWinning.set(true);
        }else{
            havaChanceWinning.set(false);
        }
        
        int seed = ran.nextInt(list.size());
        crazyResult.put(appTag, seed);
        Bitmap result = list.get(seed).getBitmap();
        
        //now , we will set the text for textview.
        //then , set onClickListener
        RemoteViews views = getRemoteView(context);
        Intent intent = new Intent();
        intent.setAction(ACTION_DESTROY_START);
        intent.putExtra(INTENT_EXTRA, EXTRA_PRODUCTDETAILACTIVITY);
        if (appTag == APP_A) {
            views.setTextViewText(R.id.tv_app_01, list.get(seed).getName());

            intent.putExtra(Constants.EXTRA_PRODUCT_ID, list.get(seed).getPid());
            intent.putExtra(Constants.EXTRA_PRODUCT_NAME, list.get(seed).getName());
            views.setOnClickPendingIntent(R.id.iv_app_01, PendingIntent.getBroadcast(context,
                    indexOfPendingIntent.getAndIncrement(), intent, PendingIntent.FLAG_UPDATE_CURRENT));
        } else if (appTag == APP_B) {
            views.setTextViewText(R.id.tv_app_02, list.get(seed).getName());

            intent.putExtra(Constants.EXTRA_PRODUCT_ID, list.get(seed).getPid());
            views.setOnClickPendingIntent(R.id.iv_app_02, PendingIntent.getBroadcast(context,
                    indexOfPendingIntent.getAndIncrement(), intent, PendingIntent.FLAG_UPDATE_CURRENT));
        } else {
            views.setTextViewText(R.id.tv_app_03, list.get(seed).getName());

            intent.putExtra(Constants.EXTRA_PRODUCT_ID, list.get(seed).getPid());
            views.setOnClickPendingIntent(R.id.iv_app_03, PendingIntent.getBroadcast(context,
                    indexOfPendingIntent.getAndIncrement(), intent, PendingIntent.FLAG_UPDATE_CURRENT));
        }
        
        
        update(context, views);
        return result;
    }
    
    /**
     * 判断是否中奖
     * @return
     */
    private boolean isCrazyWinning(){
        
        if(!havaChanceWinning.get()){
            //if no chance,return;
            return false;
        }
        
        int app_a = crazyResult.get(APP_A);
        int app_b = crazyResult.get(APP_B);
        int app_c = crazyResult.get(APP_C);


        return app_a == app_b && app_b == app_c;
    }
    
    /**
     * 提示信息
     * @param context
     * @param tip
     */
    private void showTip(final Context context,final String tip){
        if (Looper.myLooper() == null || Looper.myLooper() != Looper.getMainLooper()) {
            new Handler(Looper.getMainLooper()).post(new Runnable() {

                @Override
                public void run() {
                    Toast.makeText(context, tip, Toast.LENGTH_SHORT).show();
                }
            });
        } else {
            Toast.makeText(context, tip, Toast.LENGTH_SHORT).show();
        }
    }
    
    /**
     * 刷新widget
     * @param view
     */
    private void update(Context context, RemoteViews view){
        if(mManager == null){
            mManager = AppWidgetManager.getInstance(context);
        }
        mManager.updateAppWidget(new ComponentName(context, SlotMachinesWidget.class), view);
    }
    
    /**
     * 得到RemoteViews
     * @param context
     * @return
     */

    private RemoteViews getRemoteView(Context context){
        //must be create a new remoteView.
        return new RemoteViews(context.getPackageName(), R.layout.widget_slotmachines);
    }
    
    /**
     * reset text
     */
    private void resetText(Context context){
        RemoteViews views = getRemoteView(context);
        views.setTextViewText(R.id.tv_app_01, "");
        views.setTextViewText(R.id.tv_app_02, "");
        views.setTextViewText(R.id.tv_app_03, "");
        update(context, views);
    }
    
    /**
     * reset onClickListener
     * @param context
     */
    private void resetImageViewOnClick(Context context){
        RemoteViews views = getRemoteView(context);
        views.setOnClickPendingIntent(R.id.iv_app_01,
                PendingFactory.createActionByFlag(context, EXTRA_HOMETABACTIVITY));
        views.setOnClickPendingIntent(R.id.iv_app_02,
                PendingFactory.createActionByFlag(context, EXTRA_HOMETABACTIVITY));
        views.setOnClickPendingIntent(R.id.iv_app_03,
                PendingFactory.createActionByFlag(context, EXTRA_HOMETABACTIVITY));
        update(context, views);
    }
    
    /**
     * avoid stack overflow
     */
    private void resetIndexOfPendingIntent(){
        //avoid stack overflow
        if(indexOfPendingIntent.get() > (Integer.MAX_VALUE >>> 1)){
            indexOfPendingIntent.set(0);
        }
    }
    
    /**
     * 重置ImageView的图片
     * @param context
     */
    @SuppressWarnings("unused")
    private void resetImageView(Context context){
        //reset ImageView
        RemoteViews remoteViews = getRemoteView(context);
        Bitmap appicon = scaleBitmap(drawableToBitmap(context,appiconResource[0]));
        remoteViews.setImageViewBitmap(R.id.iv_app_01, appicon);
        remoteViews.setImageViewBitmap(R.id.iv_app_02, appicon);
        remoteViews.setImageViewBitmap(R.id.iv_app_03, appicon);
        update(context, remoteViews);
        
        remoteViews.setImageViewBitmap(R.id.iv_app_01, appicon);
    }
    
    /**
     * 尽可能的释放现有的bitmap<br>
     * 避免OOM
     */
    private void release(Context context){
        for(AppInfo app: mAppInfo){
            try {
                if(app.getIsFromInternet()){
                    //如果是网络中下载的，则自己释放掉
                    app.getBitmap().recycle();
                }
            } catch (RuntimeException e) {
                //Can't handle, powerless
            }
        }
        
        mAppInfo.clear();
    }
    
    /**
     * PendingIntent工厂
     * @author Chaos	
     *
     */
    static class PendingFactory{
        
        /*
         * fix bug: 
         * 不能直接启动Activity，因为之前启动的Activity并没有被销毁，
         * 再次启动将无法正常运行，导致老虎机点击无效
         * 2012-09-11
         */
        public static PendingIntent createActionByFlag(Context context,
                int flag) {
            Intent intent = new Intent();
            intent.setAction(ACTION_DESTROY_START);
            intent.putExtra(INTENT_EXTRA, flag);
            return PendingIntent.getBroadcast(context, indexOfPendingIntent.getAndIncrement(),
                    intent, 0);
        }

        public static PendingIntent createCommonAction(Context context, String action) {
            Intent intent = new Intent();
            intent.setAction(action);
            return PendingIntent.getBroadcast(context, indexOfPendingIntent.getAndIncrement(),
                    intent, 0);
        }
    }
    
    /**
     * 帧数控制器<br>
     * step.1: setStart(System.currentTimeMillis()) <br>
     * step.2: setFrame(frame which you want) <br>
     * step.3: setEnd  (System.currentTimeMillis())   <br>
     * step.4: getReal (the real frame,base setFrame())  <br>
     * @author Chaos	
     *
     */
    class FrameControls{
        /**帧数*/
        private long frame = 0; 
        /**开始时间*/
        private long start = 0;
        /**结束时间*/
        private long end = 0;
        /**消耗的时间*/
        private long waste = 0;
        /**最终的帧数*/
        private long real = 0;
        
        public long getStart() {
            return start;
        }
        public void setStart(long start) {
            this.start = start;
        }
        public long getEnd() {
            return end;
        }
        public void setEnd(long end) {
            this.end = end;
            this.waste = end - start;
            this.real = frame - waste > 0?(frame - waste):0;
        }
        public long getReal() {
            return real;
        }
        public long getFrame() {
            return frame;
        }
        public void setFrame(long frame) {
            this.frame = frame;
        }
    }
    
    /**
     * a structure for app
     * @author Chaos	
     */
    class AppInfo{
        

        private String name = null;

        private String pid = null;

        private String packageName = null;

        private Bitmap bitmap = null;
        private Boolean isFromInternet;
        

        public String getPackageName(){
            return packageName;
        }

        public AppInfo setPackageName(String packageName){
            this.packageName = packageName;
            return this;
        }

        public String getName() {
            return name;
        }

        public AppInfo setName(String name) {
            this.name = name;
            return this;
        }

        public String getPid() {
            return pid;
        }

        public AppInfo setPid(String pid) {
            this.pid = pid;
            return this;
        }

        public Bitmap getBitmap() {
            return bitmap;
        }

        public AppInfo setBitmap(Bitmap bitmap) {
            this.bitmap = bitmap;
            return this;
        }
        public Boolean getIsFromInternet() {
            return isFromInternet;
        }

        public AppInfo setIsFromInternet(Boolean isFromInternet) {
            this.isFromInternet = isFromInternet;
            return this;
        }
        
    }
    
}
